package com.lijing.CircleArrayQueue;
//环形队列要预留一个空间的位置作为约定，区分队列空和队列满的判断条件
public class CircleArrayQueue {
    private int maxSize;
    private int front;//指向环形队列第一个元素的位置
    private int rear;//指向环形队列最后一个元素的后面一个位置
    private int arr[];

    public int getRear() {
        return rear;
    }

    public void setRear(int rear) {
        this.rear = rear;
    }

    //构造方法
    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;//队列的大小
        this.front = 0;//指向第一个元素之前的位置
        this.rear = 0;//指向最后一个元素的位置
        this.arr = new int[maxSize];
    }
    //判断队列是否已满
    public boolean isFull(){
        return (rear + 1)%maxSize == front;//此时rear指向的是预留的空间，预留的空间一直在变化
    }
    //判断队列是否为空
    public boolean isEmpty(){
        return front == rear;
    }

    //加入元素
    public void addArrayQueue(int data){
        if(this.isFull()){//如果队列已满，无法添加元素
            System.out.println("Queue is Full!");
            return;
        }
        //因为rear指向的是最后一个元素的后一个位置，所以加元素直接加
        arr[rear] = data;
        //加完元素后，将更新rear为该元素的后一个位置,先把获取rear+1的值，然后对maxSize取模，获取下一个指向的位置
        rear = (++rear)%maxSize;

    }

    //取出元素
    public int getParam(){
        if(this.isEmpty()){//队列为空，无法取出元素
            throw new RuntimeException("队列为空，无法取出元素");
        }
        //需要使用一个中间变量来存放当前arr[front]的值
        int temp = arr[front];
        front = (++front)%maxSize;
        return temp;
        //直接取出当前元素
    }

    //遍历队列中的元素,从front开始，到rear结束，这里需要当前队列有效元素的个数
    public void showParam(){
        for (int i = front ; i < front + getNumSize(); i++) {
            System.out.printf("arr[%d] = %d\n",i%maxSize,arr[i%maxSize]);
        }
    }

    //获取当前对象的有效数据个数
    public int getNumSize(){
        return (rear-front+maxSize)%maxSize;
    }

    //显示队列的头数据
    public int peekQueue(){
        if(this.isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return arr[front];

    }
}
